//
//	Card-bitmap library
//	Copyright by J Brown 2001
//	Freeware
//
	
#include <windows.h>
#include <tchar.h>
#include "CardBitmap.h"

// Include a library-search record in the object file.
// This causes cards16.dll to be automatically linked in!
#pragma comment( lib, "cards16.lib" )

//
// Need to prototype the two undocumented functions, because
// they don't appear in windows.h
// These must be extern "C" style declarations
//
HINSTANCE	WINAPI LoadLibrary16( PSTR );
void		WINAPI FreeLibrary16( HINSTANCE );

//
//	Private card variables
//
static HDC     hMemDC     = 0;
static HBITMAP hMemBitmap = 0;
static int     __cardwidth;
static int     __cardheight;

//
//	Draw a single black line around the specified card
//
static void FixCardBitmap(HDC hMemDC, int nCardIdx, int width, int height)
{
	int xpos = nCardIdx * width;

	MoveToEx(hMemDC, xpos+2,         0, 0);
	LineTo  (hMemDC, xpos+width - 3, 0);
	LineTo  (hMemDC, xpos+width - 1, 2);
	LineTo  (hMemDC, xpos+width - 1, height - 3);	//vertical
	LineTo  (hMemDC, xpos+width - 3, height - 1);
	LineTo  (hMemDC, xpos+2,         height - 1);
	LineTo  (hMemDC, xpos+0,         height - 3);
	LineTo  (hMemDC, xpos+0,         2);
	LineTo  (hMemDC, xpos+2,         0);
}

//
//	Load all of the bitmaps from the specified DLL
//	Return the card-bitmap's width and height
//
static void LoadCardBitmapsFromLibrary(HINSTANCE hCardDll, int *pwidth, int *pheight)
{
	HBITMAP   hBitmap;
	BITMAP	  bmp;

	HDC		  hdcCard;
	HANDLE	  hOld;
	
	int		  i;
	int		  width, height;
	
	for(i = 0; i < MAX_CARD_BITMAPS; i++)
	{
		//convert into the range used by the cdt_xxx functions
		DWORD dwIndex;
		
		if(i < 52) dwIndex = (i % 4) * 13 + (i / 4);
		else       dwIndex = i;
		
		hBitmap = LoadBitmap(hCardDll, MAKEINTRESOURCE(dwIndex + 1));
		
		//
		// If first time through, setup memory-DC
		//
		if(i == 0)	
		{
			HDC hdc;

			// Find the card-bitmap dimensions
			GetObject(hBitmap, sizeof(bmp), &bmp);
			width  = bmp.bmWidth;
			height = bmp.bmHeight;

			// Create memory-DC to store ALL bitmaps in
			hdc = GetDC(0);
			
			hdcCard    = CreateCompatibleDC(hdc);
			hMemDC     = CreateCompatibleDC(hdc);
			hMemBitmap = CreateCompatibleBitmap(hdc, width * MAX_CARD_BITMAPS, height);

			SelectObject(hMemDC, hMemBitmap);
						
			ReleaseDC(0, hdc);
		}
		
		//
		//	Store the card bitmap in the memory-DC
		//
		hOld = SelectObject(hdcCard, hBitmap);
		BitBlt(hMemDC, i * width, 0, width, height, hdcCard, 0, 0, SRCCOPY);
		SelectObject(hdcCard, hOld);
		
		// Now draw a black border around each card...
		FixCardBitmap(hMemDC, i, width, height);
		
		// Release the card bitmap
		DeleteObject(hBitmap);
	}
	
	*pwidth  = width;
	*pheight = height;

	DeleteDC(hdcCard);
}

BOOL LoadCardBitmaps(int *pcardwidth, int *pcardheight)
{
	HINSTANCE hCardDll;

	//If Windows NT/2000/XP
	if(GetVersion() < 0x80000000)
	{
		hCardDll = LoadLibrary("cards.dll");

		if(hCardDll == 0)
		{
			return FALSE;
		}
		
		LoadCardBitmapsFromLibrary(hCardDll, pcardwidth, pcardheight);
		
		FreeLibrary(hCardDll);
	}
	//Else, Win9X
	else
	{
		hCardDll = LoadLibrary16("cards.dll");

		if(hCardDll == 0)
		{
			return FALSE;
		}

		LoadCardBitmapsFromLibrary(hCardDll, pcardwidth, pcardheight);

		FreeLibrary16(hCardDll);
	}

	__cardwidth  = *pcardwidth;
	__cardheight = *pcardheight;

	return TRUE;
}

void FreeCardBitmaps()
{
	if(hMemBitmap)
	{
		DeleteObject(hMemBitmap);
		DeleteDC(hMemDC);
	}
}

//
//	Draw specified card at position x, y
//
void CardBlt(HDC hdc, int x, int y, int nCardNum)
{
	int sx = nCardNum * __cardwidth;
	int sy = 0;
	int width  = __cardwidth;
	int height = __cardheight;

	//if the card bitmaps havn't been loaded..
	if(hMemDC == 0)
		return;

	//draw main center band
	BitBlt(hdc, x+2, y, width - 4, height, hMemDC, sx+2, sy+0, SRCCOPY);

	//draw the two bits to the left
	BitBlt(hdc, x,   y+2, 1, height - 4, hMemDC, sx+0, sy+2, SRCCOPY);
	BitBlt(hdc, x+1, y+1, 1, height - 2, hMemDC, sx+1, sy+1, SRCCOPY);

	//draw the two bits to the right
	BitBlt(hdc, x+width-2, y+1, 1, height - 2, hMemDC, sx+width-2, sy+1, SRCCOPY);
	BitBlt(hdc, x+width-1, y+2, 1, height - 4, hMemDC, sx+width-1, sy+2, SRCCOPY);
}
